package com.xquant.marketdata.curvestrip.service.impl;

import com.github.pagehelper.PageInfo;
import com.xquant.marketdata.curvestrip.entity.CheckParam;
import com.xquant.marketdata.curvestrip.mapper.TdefCurveMapper;
import com.xquant.marketdata.curvestrip.service.TdefCurveService;
import com.xquant.marketdata.utils.CdsFpmlUtil;
import com.xquant.marketdata.utils.DateUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * @Author: xpp -_- -_-
 * @Date: 2021/3/16 16:27
 */
@Service
public class TdefCurveServiceImpl implements TdefCurveService {


    @Autowired
    private TdefCurveMapper tdefCurveMapper;

    @Override
    public PageInfo TdefCurveListByPage(Map<String, Object> params) {
        List<Map> maps = tdefCurveMapper.TdefCurveListByPage(params);
        return new PageInfo(maps);
    }

    @Override
    public void updateTdefCurveByDeCode(Map<String, Object> params) {
        tdefCurveMapper.updateTdefCurveByDeCode(params);

        String terms = MapUtils.getString(params, "terms");
        String[] termsArray = terms.split(",");
        List<Map> refSets = tdefCurveMapper.TdefcurveRefSetByPage(params);
        //删除样本点
        tdefCurveMapper.deleteTdefcurveRefSet(params);
        //新增样本点
        Map<String, Object> setParams = new WeakHashMap<>();
        setParams.put("defcCode", params.get("defcCode"));
        setParams.put("terms", termsArray);
        setParams.put("begDate", "2000-01-01");
        setParams.put("endDate", "2050-12-31");
        setParams.put("aType", "SWP_CD");
        setParams.put("mType", "X_CNBD");
        tdefCurveMapper.saveTdefcurveRefSetBatch(setParams);

        //保存新样本点
        List<String> iCodes = saveRefCds(setParams, params, termsArray);
        List<String> delICodes = new ArrayList<>();
        for (Map refSet : refSets) {
            if (!iCodes.contains(refSet.get("I_CODE"))) {
                delICodes.add(MapUtils.getString(refSet, "I_CODE"));
            }
        }
        if (delICodes.size() > 0) {
            tdefCurveMapper.deleteRefSetCdsByICodes(delICodes);
        }
    }

    @Override
    public void saveTdefCurve(Map<String, Object> params) {
        tdefCurveMapper.saveTdefCurve(params);

        String terms = MapUtils.getString(params, "terms");
        String[] termsArray = terms.split(",");
        Map<String, Object> setParams = new WeakHashMap<>();
        setParams.put("defcCode", params.get("defcCode"));
        setParams.put("terms", termsArray);
        setParams.put("begDate", "2000-01-01");
        setParams.put("endDate", "2050-12-31");
        setParams.put("aType", "SWP_CD");
        setParams.put("mType", "X_CNBD");
        tdefCurveMapper.saveTdefcurveRefSetBatch(setParams);

        saveRefCds(setParams, params, termsArray);

    }

    private List<String> saveRefCds(Map<String, Object> setParams, Map<String, Object> params, String[] termsArray) {
        List<String> iCodes = new ArrayList<>();
        setParams.remove("terms");
        setParams.put("defcName", params.get("defcName"));
        setParams.put("referenceEntityName", params.get("entityName"));
        setParams.put("referenceEntityId", params.get("entityId"));
        setParams.put("peeingMethod", params.get("peeingMethod"));
        setParams.put("qType", MapUtils.getString(params, "qType", "").toUpperCase());
        setParams.put("mtrDateConv", "Unadjusted");
        setParams.put("country", "CN");
        setParams.put("currency", "CNY");
        setParams.put("pClass", "CDS");
        setParams.put("sType", params.get("peelingMethod"));
        setParams.put("parValue", 1);
        setParams.put("calendar", "CHINA_IB");
        setParams.put("conv", "Following");
        setParams.put("feePeriodicPayFreq", "3M");
        setParams.put("feePeriodicPayMonth", 3);
        setParams.put("feePeriodicPayDay", 20);
        setParams.put("feePeriodicDaycount", "Actual/365 (Fixed)");
        setParams.put("settleDays", 1);
        setParams.put("pipeId", 1);
        setParams.put("impDate", DateUtils.getCurrentDate());
        setParams.put("impTime", DateUtils.getCurrentDateTimeOther());
        for (String term : termsArray) {
            setParams.put("iCode", MessageFormat.format("{0}_CDS_{1}", params.get("defcCode"), term));
            setParams.put("fpml1", CdsFpmlUtil.baseFpml_1);
            setParams.put("fpml2", CdsFpmlUtil.buildCdsUnderly4Fpml(MapUtils.getString(setParams, "iCode")));
            setParams.put("fpml3", CdsFpmlUtil.baseFpml_3);
            setParams.put("fpml4", CdsFpmlUtil.buildCdsEntity4Fpml(MapUtils.getString(params, "entityId")));
            setParams.put("fpml5", CdsFpmlUtil.baseFpml_5);
            setParams.put("iName", MessageFormat.format("{0}_{1}_{2}", params.get("defcName"), params.get("entityName"), term));
            setParams.put("iNameFull", setParams.get("iName"));
            setParams.put("fstPayDateToTerm", term);
            tdefCurveMapper.saveRefSetCds(setParams);
            iCodes.add(MapUtils.getString(setParams, "iCode"));
        }
        return iCodes;
    }

    @Override
    public void deleteByPrimarydefcCode(Map<String, Object> params) {

        tdefCurveMapper.deleteRefSetCdsQuote(params);

        tdefCurveMapper.deleteRefSetCds(params);

        tdefCurveMapper.deleteTdefcurveRefSet(params);


        tdefCurveMapper.deleteByPrimarydefcCode(params);
    }

    @Override
    public PageInfo TdefcurveRefSetByPage(Map<String, Object> params) {
        List<Map> maps = tdefCurveMapper.TdefcurveRefSetByPage(params);
        return new PageInfo(maps);
    }

    @Override
    public void updateTdefcurveRefSet(Map<String, Object> params) {
        tdefCurveMapper.updateTdefcurveRefSet(params);
    }

    @Override
    public void saveTdefcurveRefSet(Map<String, Object> params) {
        tdefCurveMapper.saveTdefcurveRefSet(params);
    }

    @Override
    public void deleteTdefcurveRefSet(Map<String, Object> params) {
        tdefCurveMapper.deleteTdefcurveRefSet(params);
    }

    @Override
    public PageInfo TdefcurveRatesListByPage(Map<String, Object> params) {
        List<Map> list = tdefCurveMapper.TdefcurveRatesByPage(params);
        return new PageInfo(list);
    }

    @Override
    public void updateTdefcurveRates(Map<String, Object> params) {
        tdefCurveMapper.updateTdefcurveRates(params);
    }

    @Override
    public void saveTdefcurveRates(Map<String, Object> params) {
        //校验是否重复
        Map<String, Object> queryParam = new WeakHashMap<>();
        queryParam.put("begDate", params.get("begDate"));
        queryParam.put("defcCode", params.get("defcCode"));
        List<Map<String, Object>> list = tdefCurveMapper.selectDefcurveRates(queryParam);
        if (list != null) {
            for (Map<String, Object> map : list) {
                if (MapUtils.getString(params, "defcTerm", "").equals(map.get("DEFC_TERM"))) {
                    throw new RuntimeException("行情有重复");
                }
            }
        }
        tdefCurveMapper.saveTdefcurveRates(params);
    }

    @Override
    public void deleteTdefcurveRates(Map<String, Object> params) {
        tdefCurveMapper.deleteTdefcurveRates(params);
    }


    @Override
    public List<Map<String, Object>> findDefcurveByCode(String code) {
        return tdefCurveMapper.findDefcurveByCode(code);
    }

    @Override
    public int checkDefCurveRates(CheckParam checkParam) {
        return tdefCurveMapper.checkDefCurveRates(checkParam);
    }
}
